<?php
declare(strict_types=1);

namespace App\Utils;

use App\Constants\XZXResponseCode;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Context;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
// use Hyperf\HttpServer\Contract\ResponseInterface;
use Throwable;

/**
 * 自定义函数类
 *
 * Class CustomUtils
 * @package App\Utils
 */
class CustomUtils
{

    /**
     * 生成通道编号
     *
     * @return string
     */
    public static function createChannelNo () {
        return 'C' . time();
    }

    public static function xeServiceReturnData(int $code, string $message = '', $data = []): array
    {
        $result = [
            'code' => $code,
            'message' => $message,
            'data' => $data
        ];

        return $result;
    }

    /**
     * 操作成功返回值包装
     *
     * @param int    $code
     * @param string $message
     * @param array  $data
     *
     * @return array
     */
    public static function xzxResponseData(int $code, string $message = '', $data = []): array
    {
        return [
            "code"    => $code,
            "message" => $message == "" ? "操作成功" : $message,
            "data"    => $data,
        ];
    }

    public static function isSuccess ($re) {
        return $re['code'] == XZXResponseCode::SUCCESS_CODE;
    }

    public static function isError ($re) {
        return !self::isSuccess($re);
    }

    public static function buildSuccess ($data = [], $message = 'success', $code = XZXResponseCode::SUCCESS_CODE) {
        return self::xzxResponseData($code, $message, $data);
    }

    public static function buildError ($message, $code = XZXResponseCode::FAILED_CODE, $data = []) {
        return self::xzxResponseData($code, $message, $data);
    }

    // /**
    //  * 操作成功返回值包装
    //  *
    //  * @param array $rows
    //  * @param int $total
    //  * @param string $msg
    //  * @return array
    //  */
    // public static function xzxReturnList($rows = [], $total = 0, $msg = "")
    // {
    //     return [
    //         "code"  => 200,
    //         "msg"   => $msg == "" ? "操作成功" : $msg,
    //         "rows"  => $rows,
    //         "total" => $total
    //     ];
    // }

    // /**
    //  * 操作失败返回值包装
    //  *
    //  * @param int $code
    //  * @param array $data
    //  * @param string $msg
    //  * @return array
    //  */
    // public static function xzxReturnFailedData($msg = "", $code = 500, $data = [])
    // {
    //     return [
    //         "code"  => $code,
    //         "msg"   => $msg == "" ? "操作失败" : $msg,
    //         "data"  => $data
    //     ];
    // }

    /**
     * 自定义打印调试函数
     */
    public static function xzxDebug()
    {
        // 检查环境参数
        if (!env('APP_DEBUG')) {
            return;
        }

        $args = func_get_args();

        if (PHP_SAPI !== 'cli') echo '<pre>';

        $datetime = self::xzxGetDateTime();

        echo PHP_EOL . '---------- debug print begin ----------' . PHP_EOL . PHP_EOL;

        foreach ($args as $v) {
            if (!$v) {
                var_dump($v);
            } else {
                print_r($v);
            }
            echo PHP_EOL;
        }

        echo PHP_EOL . '---------------------------------------' . PHP_EOL;

        $debug_backtrace = debug_backtrace();

        $trace = current($debug_backtrace);

        // 获取函数名
        $func = next($debug_backtrace);
        $func = !$func ? null : $func['function'];

        echo "FILE  : {$trace['file']}" . PHP_EOL;
        echo "FUNC  : {$func}" . PHP_EOL;
        echo "LINE  : {$trace['line']}" . PHP_EOL;
        echo "TIME  : {$datetime}" . PHP_EOL;

        echo '---------- debug print end   ----------' . PHP_EOL . PHP_EOL;

        if (PHP_SAPI !== 'cli') echo '</pre>';
    }

    /**
     * 时间戳转换
     *
     * @param null $time
     * @return false|string
     */
    public static function xzxGetDateTime($time = null)
    {
        if(is_null($time)){
            $time = time();
        }
        return date('Y-m-d H:i:s', $time);
    }

    /**
     * @param $pwd
     * @param $salt
     * @return string
     */
    public static function xzxGenPassWord($pwd, $salt = "")
    {
        if ($salt = "") {
            $salt = "xzxkkkkkkk";
        }
        return  md5($pwd . '*' . $salt);
    }

    /**
     * @return mixed|string
     */
    public static function xzxGetClientIp()
    {
        try {
            /**
             * @var ServerRequestInterface $request
             */
            $request = Context::get(ServerRequestInterface::class);
            $ip_addr = $request->getHeaderLine('x-forwarded-for');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('remote-host');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('x-real-ip');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getServerParams()['remote_addr'] ?? '0.0.0.0';
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
        } catch (Throwable $e) {
            return '0.0.0.0';
        }
        return '0.0.0.0';
    }

    public static function xzxVerifyIp($realip)
    {
        return filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }

    /**
     * 根据IP获取地区
     */

    public static function getCity($ip)
    {

    }
    /**
     * 判断是否存在并且不为空
     *
     * @param $param
     *
     * @return bool
     */
    public static function xzxIsEmptyParam($param)
    {
        return (isset($param) && !empty($param));
    }

    /**
     * 当存在且不为空字符串的时候增加参数
     */
    public static function xzxAddSearch(&$param, $search, $key)
    {
        if (isset($search[$key]) && $search[$key] !== '') {

            $param[$key] = $search[$key];
        }
        return $param;
    }

    /**
     * 空对象
     */
    public static function xzxEmptyObject()
    {
        return (object)[];
    }

    /**
     * 将传入的列表或者详情中的时间戳,转换成时间字符串
     *
     * @param          $list
     * @param string[] $colList
     *
     * @return bool|mixed|void
     */
    public static function formatCreateTime ($list, $colList = ['createTime']) {

        if (Arr::isAssoc($list)) {

            $info = self::formatCreateTime([$list]);
            $info = reset($info);
            return $info;
        }

        foreach ($list as $k => $v) {

            if (is_null($v)) {
                continue;
            }

            foreach ($colList as $col) {
                if (Arr::exists($v, $col)) {
                    $v[$col] = self::xzxGetDateTime($v[$col]);
                }
            }

            $list[$k] = $v;
        }

        return $list;
    }
}
